<template>
  <div class="clients-container">
    <!-- 页面标题 -->
    <div class="page-header">
      <h2>客户端监控</h2>
      <p>实时监控所有客户端的硬件状态和在线情况</p>
    </div>

    <!-- 统计卡片 -->
    <div class="stats-cards">
      <el-row :gutter="20">
        <el-col :span="6">
          <el-card shadow="hover">
            <div class="stat-item">
              <div class="stat-content">
                <div class="stat-value">{{ stats.total }}</div>
                <div class="stat-label">总客户端数</div>
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card shadow="hover">
            <div class="stat-item online">
              <div class="stat-content">
                <div class="stat-value">{{ stats.online }}</div>
                <div class="stat-label">在线</div>
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card shadow="hover">
            <div class="stat-item offline">
              <div class="stat-content">
                <div class="stat-value">{{ stats.offline }}</div>
                <div class="stat-label">离线</div>
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card shadow="hover">
            <div class="stat-item">
              <div class="stat-content">
                <div class="stat-value">{{ stats.onlineRate }}%</div>
                <div class="stat-label">在线率</div>
              </div>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </div>

    <!-- 工具栏 -->
    <div class="toolbar">
      <div class="toolbar-left">
        <el-button :icon="Refresh" @click="loadClients">刷新</el-button>
      </div>
      <div class="toolbar-right">
        <el-select
          v-model="filters.online"
          placeholder="状态筛选"
          clearable
          style="width: 120px; margin-right: 12px"
          @change="loadClients"
        >
          <el-option label="全部" value="" />
          <el-option label="在线" value="1" />
          <el-option label="离线" value="0" />
        </el-select>
        <el-select
          v-model="filters.platform"
          placeholder="平台筛选"
          clearable
          style="width: 120px; margin-right: 12px"
          @change="loadClients"
        >
          <el-option label="全部" value="" />
          <el-option label="Windows" value="win32" />
          <el-option label="macOS" value="darwin" />
          <el-option label="Linux" value="linux" />
        </el-select>
        <el-input
          v-model="filters.search"
          placeholder="搜索客户端ID/主机名/IP/用户"
          :prefix-icon="Search"
          clearable
          style="width: 280px"
          @input="handleSearch"
        />
      </div>
    </div>

    <!-- 客户端列表 -->
    <el-table
      :data="clients"
      v-loading="loading"
      class="client-table"
    >
      <el-table-column label="状态" width="100">
        <template #default="{ row }">
          <el-tag v-if="row.is_online" type="success" size="small" effect="plain">
            <el-icon><Connection /></el-icon>
            在线
          </el-tag>
          <el-tag v-else type="info" size="small" effect="plain">
            离线
          </el-tag>
        </template>
      </el-table-column>

      <el-table-column label="客户端ID" min-width="180">
        <template #default="{ row }">
          <span class="client-id" :title="row.client_id">
            {{ formatClientId(row.client_id) }}
          </span>
        </template>
      </el-table-column>

      <el-table-column label="用户" width="150">
        <template #default="{ row }">
          <span v-if="row.username">{{ row.nickname || row.username }}</span>
          <span v-else class="no-user">未绑定</span>
        </template>
      </el-table-column>

      <el-table-column label="主机名" width="150" prop="hostname" />

      <el-table-column label="平台" width="100">
        <template #default="{ row }">
          <el-tag size="small" effect="plain">
            {{ formatPlatform(row.platform) }}
          </el-tag>
        </template>
      </el-table-column>

      <el-table-column label="IP地址" width="140">
        <template #default="{ row }">
          <span v-if="row.is_online">{{ row.ip_address || '-' }}</span>
          <span v-else class="offline-text">-</span>
        </template>
      </el-table-column>

      <el-table-column label="CPU使用率" width="150">
        <template #default="{ row }">
          <div v-if="row.is_online && row.cpu_usage !== null" class="metric">
            <el-progress
              :percentage="Number(row.cpu_usage)"
              :color="getUsageColor(row.cpu_usage)"
              :format="() => `${row.cpu_usage}%`"
            />
          </div>
          <span v-else class="offline-text">-</span>
        </template>
      </el-table-column>

      <el-table-column label="内存使用率" width="150">
        <template #default="{ row }">
          <div v-if="row.is_online && row.memory_usage !== null" class="metric">
            <el-progress
              :percentage="Number(row.memory_usage)"
              :color="getUsageColor(row.memory_usage)"
              :format="() => `${row.memory_usage}%`"
            />
          </div>
          <span v-else class="offline-text">-</span>
        </template>
      </el-table-column>

      <el-table-column label="磁盘使用率" width="150">
        <template #default="{ row }">
          <div v-if="row.is_online && row.disk_info && row.disk_info.length > 0" class="metric">
            <el-progress
              :percentage="Number(row.disk_info[0].usage)"
              :color="getUsageColor(row.disk_info[0].usage)"
              :format="() => `${row.disk_info[0].usage}%`"
            />
          </div>
          <span v-else class="offline-text">-</span>
        </template>
      </el-table-column>

      <el-table-column label="最后心跳" width="140">
        <template #default="{ row }">
          {{ formatTime(row.last_heartbeat, row) }}
        </template>
      </el-table-column>

      <el-table-column label="操作" width="160" fixed="right">
        <template #default="{ row }">
          <el-button link type="primary" @click="viewDetail(row)">
            详情
          </el-button>
          <el-button link type="danger" @click="deleteClient(row)">
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <div class="pagination">
      <el-pagination
        v-model:current-page="pagination.page"
        v-model:page-size="pagination.pageSize"
        :page-sizes="[10, 20, 50, 100]"
        :total="pagination.total"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handlePageChange"
      />
    </div>

    <!-- 客户端详情弹窗 -->
    <el-dialog
      v-model="showDetail"
      title="客户端详情"
      width="900px"
      :close-on-click-modal="false"
    >
      <div v-if="selectedClient" class="detail-content">
          <!-- 基本信息 -->
          <div class="detail-section">
            <h3>基本信息</h3>
            <div class="detail-grid">
              <div class="detail-item">
                <label>客户端ID:</label>
                <span>{{ selectedClient.client_id }}</span>
              </div>
              <div class="detail-item">
                <label>用户:</label>
                <span>{{ selectedClient.username || '-' }}</span>
              </div>
              <div class="detail-item">
                <label>主机名:</label>
                <span>{{ selectedClient.hostname }}</span>
              </div>
              <div class="detail-item">
                <label>平台:</label>
                <span>{{ formatPlatform(selectedClient.platform) }}</span>
              </div>
              <div class="detail-item">
                <label>系统类型:</label>
                <span>{{ selectedClient.os_type }}</span>
              </div>
              <div class="detail-item">
                <label>系统版本:</label>
                <span>{{ selectedClient.os_release }}</span>
              </div>
              <div class="detail-item">
                <label>架构:</label>
                <span>{{ selectedClient.arch }}</span>
              </div>
              <div class="detail-item">
                <label>IP地址:</label>
                <span>{{ selectedClient.ip_address }}</span>
              </div>
            </div>
          </div>

          <!-- MAC地址 -->
          <div class="detail-section" v-if="selectedClient.mac_addresses && selectedClient.mac_addresses.length > 0">
            <h3>MAC地址</h3>
            <div class="mac-list">
              <span v-for="(mac, index) in selectedClient.mac_addresses" :key="index" class="mac-tag">
                {{ mac }}
              </span>
            </div>
          </div>

          <!-- CPU信息 -->
          <div class="detail-section">
            <h3>CPU信息</h3>
            <div class="detail-grid">
              <div class="detail-item">
                <label>型号:</label>
                <span>{{ selectedClient.cpu_model }}</span>
              </div>
              <div class="detail-item">
                <label>核心数:</label>
                <span>{{ selectedClient.cpu_cores }}</span>
              </div>
              <div class="detail-item">
                <label>使用率:</label>
                <span class="usage-value" :style="{color: getUsageColor(selectedClient.cpu_usage)}">
                  {{ selectedClient.cpu_usage }}%
                </span>
              </div>
            </div>
          </div>

          <!-- 内存信息 -->
          <div class="detail-section">
            <h3>内存信息</h3>
            <div class="detail-grid">
              <div class="detail-item">
                <label>总容量:</label>
                <span>{{ formatBytes(selectedClient.total_memory) }}</span>
              </div>
              <div class="detail-item">
                <label>可用:</label>
                <span>{{ formatBytes(selectedClient.free_memory) }}</span>
              </div>
              <div class="detail-item">
                <label>使用率:</label>
                <span class="usage-value" :style="{color: getUsageColor(selectedClient.memory_usage)}">
                  {{ selectedClient.memory_usage }}%
                </span>
              </div>
            </div>
          </div>

          <!-- 磁盘信息 -->
          <div class="detail-section" v-if="selectedClient.disk_info && selectedClient.disk_info.length > 0">
            <h3>磁盘信息</h3>
            <div class="disk-list">
              <div v-for="(disk, index) in selectedClient.disk_info" :key="index" class="disk-item">
                <div class="disk-mount">{{ disk.mount }}</div>
                <div class="disk-bar">
                  <div class="progress-bar">
                    <div class="progress-fill" 
                      :style="{width: disk.usage + '%', backgroundColor: getUsageColor(disk.usage)}">
                    </div>
                  </div>
                  <span class="disk-info-text">
                    {{ formatBytes(disk.used) }} / {{ formatBytes(disk.total) }} ({{ disk.usage }}%)
                  </span>
                </div>
              </div>
            </div>
          </div>

          <!-- 网络流量 -->
          <div class="detail-section">
            <h3>网络流量</h3>
            <div class="detail-grid">
              <div class="detail-item">
                <label>接收:</label>
                <span>{{ formatBytes(selectedClient.network_rx) }}</span>
              </div>
              <div class="detail-item">
                <label>发送:</label>
                <span>{{ formatBytes(selectedClient.network_tx) }}</span>
              </div>
            </div>
          </div>

          <!-- 时间信息 -->
          <div class="detail-section">
            <h3>时间信息</h3>
            <div class="detail-grid">
              <div class="detail-item">
                <label>最后心跳:</label>
                <span>{{ formatFullTime(selectedClient.last_heartbeat) }}</span>
              </div>
              <div class="detail-item">
                <label>最后上报:</label>
                <span>{{ formatFullTime(selectedClient.last_report_at) }}</span>
              </div>
              <div class="detail-item">
                <label>创建时间:</label>
                <span>{{ formatFullTime(selectedClient.created_at) }}</span>
              </div>
            </div>
          </div>
        </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Refresh, Search, Connection } from '@element-plus/icons-vue'
import axios from '@/api'

const clients = ref([])
const stats = reactive({
  total: 0,
  online: 0,
  offline: 0,
  onlineRate: 0
})
const pagination = reactive({
  page: 1,
  pageSize: 20,
  total: 0,
  totalPages: 0
})
const filters = reactive({
  online: '',
  platform: '',
  search: ''
})
const loading = ref(false)
const showDetail = ref(false)
const selectedClient = ref(null)
let searchTimer = null
let refreshTimer = null

// 加载统计信息
const loadStats = async () => {
  try {
    const response = await axios.get('/api/clients/stats')
    if (response.data.success) {
      Object.assign(stats, response.data.data)
    }
  } catch (error) {
    console.error('加载统计信息失败:', error)
  }
}

// 加载客户端列表
const loadClients = async () => {
  loading.value = true
  try {
    const params = {
      page: pagination.page,
      pageSize: pagination.pageSize,
      ...filters
    }
    
    const response = await axios.get('/api/clients/list', { params })
    
    if (response.data.success) {
      clients.value = response.data.data.clients
      Object.assign(pagination, response.data.data.pagination)
    }
  } catch (error) {
    console.error('加载客户端列表失败:', error)
    ElMessage.error('加载失败，请重试')
  } finally {
    loading.value = false
  }
}

// 搜索处理
const handleSearch = () => {
  if (searchTimer) {
    clearTimeout(searchTimer)
  }
  searchTimer = setTimeout(() => {
    pagination.page = 1
    loadClients()
  }, 500)
}

// 分页处理
const handleSizeChange = (size) => {
  pagination.pageSize = size
  pagination.page = 1
  loadClients()
}

const handlePageChange = (page) => {
  pagination.page = page
  loadClients()
}

// 查看详情
const viewDetail = (client) => {
  selectedClient.value = client
  showDetail.value = true
}

// 关闭详情
const closeDetail = () => {
  showDetail.value = false
  selectedClient.value = null
}

// 删除客户端
const deleteClient = async (client) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除客户端 "${client.hostname || client.client_id}" 吗？`,
      '提示',
      {
        type: 'warning'
      }
    )
    
    const response = await axios.delete(`/api/clients/${client.client_id}`)
    if (response.data.success) {
      ElMessage.success('删除成功')
      loadStats()
      loadClients()
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除客户端失败:', error)
      ElMessage.error('删除失败，请重试')
    }
  }
}

// 格式化客户端ID
const formatClientId = (id) => {
  if (!id) return '-'
  if (id.length <= 20) return id
  return id.substring(0, 10) + '...' + id.substring(id.length - 10)
}

// 格式化平台
const formatPlatform = (platform) => {
  const platforms = {
    'win32': 'Windows',
    'darwin': 'macOS',
    'linux': 'Linux'
  }
  return platforms[platform] || platform || '-'
}

// 格式化字节数
const formatBytes = (bytes) => {
  if (!bytes || bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 格式化时间（相对时间）
const formatTime = (time, row = null) => {
  if (!time) return '-'
  
  // 优先使用时间戳（避免时区问题）
  let date
  if (row && row.last_heartbeat_ts) {
    // 使用UNIX时间戳（毫秒）
    date = new Date(row.last_heartbeat_ts)
  } else if (typeof time === 'number') {
    // 如果time本身就是时间戳
    date = new Date(time)
  } else if (typeof time === 'string') {
    // 字符串时间，需要处理时区
    // MySQL返回的是本地时区时间，需要手动调整
    date = new Date(time.replace(' ', 'T') + '+08:00')
  } else {
    date = new Date(time)
  }
  
  // 检查日期是否有效
  if (isNaN(date.getTime())) {
    return '-'
  }
  
  const now = new Date()
  const diff = Math.floor((now - date) / 1000)
  
  // 如果时间差为负数（未来时间），说明有时区问题
  if (diff < 0) {
    return '刚刚'
  }
  
  if (diff < 10) return '刚刚'
  if (diff < 60) return `${diff}秒前`
  if (diff < 3600) return `${Math.floor(diff / 60)}分钟前`
  if (diff < 86400) return `${Math.floor(diff / 3600)}小时前`
  if (diff < 604800) return `${Math.floor(diff / 86400)}天前`
  
  // 超过7天显示完整日期
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    timeZone: 'Asia/Shanghai'
  })
}

// 格式化完整时间
const formatFullTime = (time) => {
  if (!time) return '-'
  const date = new Date(time)
  return date.toLocaleString('zh-CN')
}

// 获取使用率颜色
const getUsageColor = (usage) => {
  if (usage >= 90) return '#f56c6c'
  if (usage >= 70) return '#e6a23c'
  return '#67c23a'
}

// 生命周期
onMounted(() => {
  loadStats()
  loadClients()
  
  // 🔥 自动刷新（每10秒）
  refreshTimer = setInterval(() => {
    loadStats()
    loadClients()
  }, 10000)
})

onBeforeUnmount(() => {
  if (refreshTimer) {
    clearInterval(refreshTimer)
  }
  if (searchTimer) {
    clearTimeout(searchTimer)
  }
})
</script>

<style scoped>
/* 页面容器 */
.clients-container {
  padding: 24px;
}

/* 页面标题 */
.page-header {
  margin-bottom: 24px;
}

.page-header h2 {
  font-size: 24px;
  font-weight: 600;
  color: #303133;
  margin: 0 0 8px 0;
}

.page-header p {
  font-size: 14px;
  color: #909399;
  margin: 0;
}

/* 统计卡片 */
.stats-cards {
  margin-bottom: 20px;
}

.stat-item {
  padding: 8px 0;
  text-align: center;
}

.stat-content {
  width: 100%;
}

.stat-value {
  font-size: 28px;
  font-weight: 600;
  color: #303133;
  line-height: 1;
  margin-bottom: 8px;
}

.stat-label {
  font-size: 14px;
  color: #909399;
}

.stat-item.online .stat-value {
  color: #67c23a;
}

.stat-item.offline .stat-value {
  color: #909399;
}

/* 工具栏 */
.toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding: 16px;
  background: #ffffff;
  border-radius: 4px;
}

.toolbar-left {
  display: flex;
  gap: 12px;
}

.toolbar-right {
  display: flex;
  align-items: center;
}

/* 表格样式 */
.client-table {
  background: #ffffff;
}

.client-id {
  font-family: 'Courier New', monospace;
  font-size: 13px;
  color: #606266;
}

.no-user {
  color: #c0c4cc;
  font-style: italic;
}

.offline-text {
  color: #c0c4cc;
  font-style: italic;
}

/* 分页 */
.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}

/* 详情内容 */
.detail-content {
  max-height: 600px;
  overflow-y: auto;
}

.detail-section {
  margin-bottom: 24px;
}

.detail-section h3 {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 16px;
  padding-left: 12px;
  border-left: 3px solid #409eff;
}

.detail-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}

.detail-item {
  display: flex;
  align-items: center;
  padding: 12px;
  background: #f5f7fa;
  border-radius: 4px;
}

.detail-item label {
  font-weight: 500;
  color: #606266;
  min-width: 100px;
  font-size: 14px;
}

.detail-item span {
  color: #303133;
  font-size: 14px;
  word-break: break-all;
  flex: 1;
}

.mac-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.mac-tag {
  padding: 6px 12px;
  background: #ecf5ff;
  border: 1px solid #d9ecff;
  border-radius: 4px;
  font-family: 'Courier New', monospace;
  font-size: 13px;
  color: #409eff;
}

.disk-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.disk-item {
  padding: 16px;
  background: #f5f7fa;
  border-radius: 4px;
}

.disk-mount {
  font-weight: 600;
  margin-bottom: 12px;
  color: #303133;
  font-size: 14px;
}

.disk-bar {
  display: flex;
  align-items: center;
  gap: 12px;
}

.disk-info-text {
  font-size: 13px;
  color: #606266;
  white-space: nowrap;
  min-width: 200px;
  text-align: right;
}
</style>
